import os
import openpyxl
import imaplib
import email
import shutil
from tqdm import tqdm
from email.header import decode_header
import logging
from datetime import datetime
import threading
import chardet
import ftfy

logging.basicConfig(filename='email_backup.log', level=logging.INFO)

def backup_email(email_address, password):
    imap_server = 'imap.qiye.aliyun.com'
    imap_port = 993
    imap_connection = imaplib.IMAP4_SSL(imap_server, imap_port)
    imap_connection.login(email_address, password)

    folders = ['INBOX', 'Sent','Deleted']

    folder_name = f"{email_address.split('@')[0]}@{email_address.split('@')[1]}"
    if not os.path.exists(folder_name):
        os.makedirs(folder_name)

    for folder in folders:
        imap_connection.select(folder)
        # imap_connection.enable("offline")

        message_numbers_raw = imap_connection.search(None, 'ALL')
        message_numbers = message_numbers_raw[1][0].split()

        sub_folder_name = os.path.join(folder_name, folder)

        if not os.path.exists(sub_folder_name):
            os.makedirs(sub_folder_name)

        progress = tqdm(message_numbers, desc=f'当前备份的邮箱为：{email_address}({folder})', unit='封')
        for message_number in progress:
            _, message_data = imap_connection.fetch(message_number, '(RFC822)')
            message = email.message_from_bytes(message_data[0][1])
            
            subject = message["Subject"]

            if subject is not None:
                result = chardet.detect(subject.encode())
                encoding = result['encoding'] if result['encoding'] is not None else 'utf-8'
                subject_decoded = subject.encode(encoding).decode('utf-8')
            else:
                subject_decoded = ""

            # B方案可以解决邮件头编码格式
            # if subject is not None:
            #     subject_decoded = ftfy.fix_text(subject)
            # else:
            #     subject_decoded = ""

            
            subject_decoded = decode_header(subject_decoded)

            subject_str = '_'
            for part in subject_decoded:
                if isinstance(part[0], bytes):
                    try:
                        subject_str += part[0].decode(part[1] or 'utf-8')
                    except:
                        pass
                else:
                    subject_str += part[0]

            try:
                message_file_name = f'{subject_str}_{message["Date"].replace(":", "_")}'
            except:
                logging.info(f'{message_file_name}无法解析，时间：{datetime.now()}')
                message_file_name = f'{subject_str}_'
                
            message_file_name = "." + message_file_name

            message_file_name = ''.join(filter(str.isalnum, message_file_name))
            with open(os.path.join(sub_folder_name, message_file_name+'.eml'), 'wb') as f:
                f.write(message.as_bytes())

            progress.set_description(f'当前备份的邮箱为：{email_address}({folder})，进度')

    logging.info(f'{email_address}已备份完成,备份完成的时间为：{datetime.now()}')
    print(f'{email_address}已备份完成')

    imap_connection.close()
    imap_connection.logout()

if __name__ == '__main__':
    wb = openpyxl.load_workbook('email.xlsx')
    sheet = wb.active

    email_list = []
    for row in sheet.iter_rows(min_row=2, values_only=True):
        email_address, password = row
        email_list.append((email_address, password))

    threads = []
    for email_address, password in email_list:
        t = threading.Thread(target=backup_email, args=(email_address, password))
        threads.append(t)
        t.start()

    for thread in threads:
        thread.join()

    
    
